/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.entity.MaintainPlanTemplate;
import org.springblade.modules.admin.entity.MaintainTemplate;
import org.springblade.modules.admin.entity.MaintainTemplateRelation;
import org.springblade.modules.admin.mapper.MaintainTemplateRelationMapper;
import org.springblade.modules.admin.service.IMaintainPlanRelationService;
import org.springblade.modules.admin.service.IMaintainPlanTemplateService;
import org.springblade.modules.admin.service.MaintainTemplateRelationService;
import org.springblade.modules.admin.service.MaintainTemplateService;
import org.springblade.modules.admin.vo.TemplateContentRelationPageVO;
import org.springblade.modules.admin.vo.TemplateLocationTypeTreeVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Date 14:02 2022/3/14
 * @Description {
 *   MaintainTemplateRelationServiceImpl
 * }
 * @Author lsay
 **/
@Service
public class MaintainTemplateRelationServiceImpl extends BaseServiceImpl<MaintainTemplateRelationMapper, MaintainTemplateRelation> implements MaintainTemplateRelationService {

	@Autowired
	@Lazy
	private MaintainTemplateService templateService;
	@Autowired
	private IMaintainPlanTemplateService planTemplateService;

	@Override
	public List<TemplateLocationTypeTreeVO> tree(Long templateId) {
		List<TemplateLocationTypeTreeVO> typeTreeVOS = baseMapper.tree(templateId);
		typeTreeVOS = change(typeTreeVOS,templateId);
		return typeTreeVOS;
	}

	/**
	 * 递归模板分类Tree 封装对应工作项数据
	 * @param typeTreeVOS
	 * @param templateId
	 * @return
	 */
	private List<TemplateLocationTypeTreeVO> change(List<TemplateLocationTypeTreeVO> typeTreeVOS,Long templateId){
		typeTreeVOS.forEach(e -> {
			if (ObjectUtil.isEmpty(e.getChildren())){
				Integer workItemCount = super.count(Wrappers.<MaintainTemplateRelation>lambdaQuery()
					.eq(MaintainTemplateRelation::getTltId,e.getTltId()).eq(MaintainTemplateRelation::getTemplateId,templateId).isNotNull(MaintainTemplateRelation::getContentId));
				e.setContentCount(workItemCount);
			}else {
				change(e.getChildren(),templateId);
			}
			e = doCount(e,new HashMap<>());
		});
		return typeTreeVOS;
	}

	/**
	 * 树形结构展示的某个节点的统计数值=所有子节点工作项数量总和
	 * @param root
	 * @param result
	 * @return
	 */
	public static TemplateLocationTypeTreeVO doCount(TemplateLocationTypeTreeVO root, Map<String,Object> result){
		int count = 0;
		List<TemplateLocationTypeTreeVO> list = root.getChildren();
		if(ObjectUtil.isEmpty(list)){
			count = root.getContentCount();
			root.setContentCount(count);
			return root;
		}

		for (TemplateLocationTypeTreeVO child : list) {
			//统计子节点的孩子总数
			int cur_cnt=doCount( child,result).getContentCount();
			result.put(String.valueOf(child.getTltId()), cur_cnt);
			count += cur_cnt;
			root.setContentCount(count);
		}

		//返回前记录当前节点的统计个数
		result.put(String.valueOf(root.getTltId()), count);
		return root;
	}

	@Override
	public List<TemplateContentRelationPageVO> contentList(Long templateId, Long tltId) {
		return baseMapper.selectContentList(templateId,tltId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean contentSave(MaintainTemplateRelation templateRelation) {
		List<MaintainTemplateRelation> templateRelations = templateRelation.getTemplateRelations();
		if(ObjectUtil.isNotEmpty(templateRelations)){
			this.saveBatch(templateRelations);
		}
//		if(ObjectUtil.isNotEmpty(templateRelations)){
//			this.saveOrUpdateBatch(templateRelations);
//			List<Long> ids = templateRelations.stream().map(BaseEntity::getId).collect(Collectors.toList());
//			this.remove(Wrappers.<MaintainTemplateRelation>lambdaQuery()
//				.notIn(MaintainTemplateRelation::getId,ids).isNotNull(MaintainTemplateRelation::getContentId)
//			);
//		}else {
//			this.remove(Wrappers.<MaintainTemplateRelation>lambdaQuery()
//				.eq(MaintainTemplateRelation::getTemplateId,templateRelation.getTemplateId())
//				.eq(MaintainTemplateRelation::getTltId,templateRelation.getTltId())
//				.isNotNull(MaintainTemplateRelation::getContentId));
//		}
		updateTemplateWorkItemCount(templateRelation.getTemplateId());
		return Boolean.TRUE;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean removeContent(Long templateId, List<Long> ids) {
		this.removeByIds(ids);
		updateTemplateWorkItemCount(templateId);
		return Boolean.TRUE;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean removeTemplateType(String ids, Long templateId) {
		this.remove(Wrappers.<MaintainTemplateRelation>lambdaQuery().eq(MaintainTemplateRelation::getTemplateId,templateId)
			.and(e -> e.in(MaintainTemplateRelation::getTltId, Func.toLongList(ids)).or().in(MaintainTemplateRelation::getTltParentId,Func.toLongList(ids))));
		return updateTemplateWorkItemCount(templateId);
	}

	@Override
	public Boolean updateTemplateWorkItemCount(Long templateId){
		int planTemplateCount = planTemplateService.count(Wrappers.<MaintainPlanTemplate>lambdaQuery().eq(MaintainPlanTemplate::getTemplateId,templateId));
		int count = this.count(Wrappers.<MaintainTemplateRelation>lambdaQuery()
			.eq(MaintainTemplateRelation::getTemplateId,templateId).isNotNull(MaintainTemplateRelation::getContentId));
		if(planTemplateCount != 0 && count == 0){
			throw new ServiceException("删除的模板至少保留一条工作项关联！");
		}
		return templateService.update(Wrappers.<MaintainTemplate>lambdaUpdate().eq(MaintainTemplate::getId,templateId).set(MaintainTemplate::getWorkItemCount,count));
	}

}

